﻿using Microsoft.Win32;
using MongoDB.Bson;
using Sustainalytics.Download.Entities;
using Sustainalytics.Download.GridFs;
using Sustainalytics.Download.View.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sustainalytics.Download.View
{
    public class ViewModel : NotifyPropertyChanged
    {
        DownloadFromGridFs _downloadInstance;

        public ViewModel(DownloadFromGridFs downloadInstance)
        {
            _downloadInstance = downloadInstance;
        }



        public ObservableCollection<GridFsFile> FileList { get; set; }

        private int _filesCount = 0;
        public int FilesCount
        {
            get { return _filesCount; }
            set
            {
                if (_filesCount != value)
                {
                    _filesCount = value;
                    RaisePropertyChanged();
                }
            }
        }

        private int _page = 1;
        public int Page {
            get { return _page; }
            set
            {
                if (_page != value)
                {
                    _page = value;
                    FileList.Clear();
                    FileList.InsertRange(_downloadInstance.GetFilesList(Page, Take, GetProductInvolvementFilesOnly).Result);
                    RaisePropertyChanged();
                }
            }
        }

        private bool _getProductInvolvementFileOnly = false;
        public bool GetProductInvolvementFilesOnly
        {
            get { return _getProductInvolvementFileOnly; }
            set
            {
                if (_getProductInvolvementFileOnly != value)
                {
                    _getProductInvolvementFileOnly = value;
                    FileList.Clear();
                    FileList.InsertRange(_downloadInstance.GetFilesList(Page, Take, GetProductInvolvementFilesOnly).Result);
                    FilesCount = _downloadInstance.GetFilesCount(GetProductInvolvementFilesOnly).Result;
                    RaisePropertyChanged();
                }
            }
        }

        private int _take = 10;
        public int Take
        {
            get { return _take; }
            set
            {
                if (_take != value)
                {
                    _take = value;
                    FileList.Clear();
                    FileList.InsertRange(_downloadInstance.GetFilesList(Page, Take, GetProductInvolvementFilesOnly).Result);
                    RaisePropertyChanged();
                }
            }
        }

        public IEnumerable<int> PageSizes { get; set; }

        #region DownloadCommand
        private RelayCommand _downloadCommand;
        public ICommand DownloadCommand
        {
            get
            {
                if (_downloadCommand == null)
                {
                    _downloadCommand = new RelayCommand(
                        param => DownloadFile(ObjectId.Parse(param.ToString())),
                        param => CanDownload()
                        );
                }
                return _downloadCommand;
            }
        }

        private bool CanDownload() => true;

        private void DownloadFile(ObjectId param)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            var file = _downloadInstance.GetFile(param).Result;

            saveFileDialog.FileName = file.Name;
            saveFileDialog.DefaultExt = $".{file.Extension}";

            bool? result = saveFileDialog.ShowDialog();

            if (result == true)
            {
                using (var stream = saveFileDialog.OpenFile())
                {
                    var fileArray = _downloadInstance.GetFileContent(param).Result;

                    stream.Write(fileArray, 0, fileArray.Length);
                }
            }
        }

        #endregion

        #region ChangePageCommand

        private RelayCommand _changePageCommand;
        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand(
                        param => ChangePage(int.Parse(param.ToString())),
                        param => CanChangePage(int.Parse(param.ToString()))
                        );
                }
                return _changePageCommand;
            }
        }

        private bool CanChangePage(int changed) {
            if (Page + changed < 1)
                return false;

            if (Page + changed > FilesCount / Take)
                return false;

            return true;
        }

        private void ChangePage(int changed)
        {
            Page = Page + changed;
        }

        #endregion
    }
}
